package com.bpz.utils;

import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.URL;
import java.net.UnknownHostException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

public abstract class StringUtils {

    private static Logger logger = Logger.getLogger(StringUtils.class);

    /**
     * md5加密32位
     *
     * @param str 需要加密的字符串
     * @return 加码后的字符串
     */
    public static String md5(String str) {
        try {
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");
            messageDigest.update(str.getBytes());
            String text = toHex(messageDigest.digest());
            return text;
        } catch (NoSuchAlgorithmException e) {
            return "";
        }
    }

    /**
     * 获取GUID
     *
     * @return
     */
    public static String getGuid() {
        UUID uuid = UUID.randomUUID();
        String str=uuid.toString();
        str=str.replaceAll("-","");
        return str;
    }

    /**
     * 转为16进制
     *
     * @param buffer
     * @return
     */
    private static String toHex(byte buffer[]) {
        StringBuffer sb = new StringBuffer(buffer.length * 2);
        for (int i = 0; i < buffer.length; i++) {
            sb.append(Character.forDigit((buffer[i] & 240) >> 4, 16));
            sb.append(Character.forDigit(buffer[i] & 15, 16));
        }

        return sb.toString();
    }

    /**
     * 返回未登录时的结果
     *
     * @return
     */
    public static ReturnResult noLogin() {
        ReturnResult result = new ReturnResult();
        result.setStatus(Status.NOLOGIN);
        result.setMsg(i18nUtils.getVal("200001005"));
        return result;
    }

    /**
     * 返回无权限的结果
     *
     * @return
     */
    public static ReturnResult noPower() {
        ReturnResult result = new ReturnResult();
        result.setStatus(Status.NOPOWER);
        result.setMsg(i18nUtils.getVal("200001006"));
        return result;
    }

    /**
     * Example: subString("12345","1","4")=23
     *
     * @param src
     * @param start
     * @param to
     * @return
     */
    public static Integer subStringToInteger(String src, String start, String to) {
        return stringToInteger(subString(src, start, to));
    }

    /**
     * Example: subString("abcd","a","c")="b"
     *
     * @param src
     * @param start null while start from index=0
     * @param to    null while to index=src.length
     * @return
     */
    public static String subString(String src, String start, String to) {
        int indexFrom = start == null ? 0 : src.indexOf(start);
        int indexTo = to == null ? src.length() : src.indexOf(to);
        if (indexFrom < 0 || indexTo < 0 || indexFrom > indexTo) {
            return null;
        }
        indexFrom += start.length();
        return src.substring(indexFrom, indexTo);

    }

    /**
     * 字段串转为整型
     *
     * @param in
     * @return null或数字
     */
    public static Integer stringToInteger(String in) {
        if (in == null) {
            return null;
        }
        in = in.trim();
        if (in.length() == 0) {
            return null;
        }

        try {
            return Integer.parseInt(in);
        } catch (NumberFormatException e) {
            logger.warn("stringToInteger fail,string=" + in, e);
            return null;
        }
    }

    /**
     * 全等于
     *
     * @param a
     * @param b
     * @return
     */
    public static boolean equals(String a, String b) {
        if (a == null) {
            return b == null;
        }
        return a.equals(b);
    }

    /**
     * 忽略大小写
     *
     * @param a
     * @param b
     * @return
     */
    public static boolean equalsIgnoreCase(String a, String b) {
        if (a == null) {
            return b == null;
        }
        return a.equalsIgnoreCase(b);
    }

    public static boolean isEmpty(String value) {
        if (value == null || value.length() == 0) {
            return true;
        }

        return false;
    }

    public static int lowerHashCode(String text) {
        if (text == null) {
            return 0;
        }
        // return text.toLowerCase().hashCode();
        int h = 0;
        for (int i = 0; i < text.length(); ++i) {
            char ch = text.charAt(i);
            if (ch >= 'A' && ch <= 'Z') {
                ch = (char) (ch + 32);
            }

            h = 31 * h + ch;
        }
        return h;
    }

    /**
     * escape编码
     *
     * @param src
     * @return
     */
    public static String escape(String src) {
        int i;
        char j;
        StringBuffer tmp = new StringBuffer();
        tmp.ensureCapacity(src.length() * 6);

        for (i = 0; i < src.length(); i++) {

            j = src.charAt(i);

            if (Character.isDigit(j) || Character.isLowerCase(j) || Character.isUpperCase(j))
                tmp.append(j);
            else if (j < 256) {
                tmp.append("%");
                if (j < 16)
                    tmp.append("0");
                tmp.append(Integer.toString(j, 16));
            } else {
                tmp.append("%u");
                tmp.append(Integer.toString(j, 16));
            }
        }
        return tmp.toString();
    }

    public static String unescape(String src) {
        StringBuffer tmp = new StringBuffer();
        tmp.ensureCapacity(src.length());
        int lastPos = 0, pos = 0;
        char ch;
        while (lastPos < src.length()) {
            pos = src.indexOf("%", lastPos);
            if (pos == lastPos) {
                if (src.charAt(pos + 1) == 'u') {
                    ch = (char) Integer.parseInt(src.substring(pos + 2, pos + 6), 16);
                    tmp.append(ch);
                    lastPos = pos + 6;
                } else {
                    ch = (char) Integer.parseInt(src.substring(pos + 1, pos + 3), 16);
                    tmp.append(ch);
                    lastPos = pos + 3;
                }
            } else {
                if (pos == -1) {
                    tmp.append(src.substring(lastPos));
                    lastPos = src.length();
                } else {
                    tmp.append(src.substring(lastPos, pos));
                    lastPos = pos;
                }
            }
        }
        return tmp.toString();
    }

    /**
     * PrintWriter out.print写数据
     *
     * @param response HttpServletResponse
     * @param content  内容
     */
    public static void write(HttpServletResponse response, String content) {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out;
        try {
            out = response.getWriter();
            out.print(content);
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * 字符串转为date类型
     *
     * @param dateStr
     * @param format
     * @return
     * @throws java.text.ParseException
     */
    public static Date strToDate(String dateStr, String format) {
        if (dateStr.indexOf("+")!=-1)
        {
            dateStr=dateStr.replace("+"," ");
        }
        DateFormat fmt = new SimpleDateFormat(format);
        try {
            return fmt.parse(dateStr);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 获取搜索条件的字典
     *
     * @param request
     * @return
     */
    public static Map<String, Object> getSearchMap(HttpServletRequest request) {
        String startTime = request.getParameter("startTime");
        String endTime = request.getParameter("endTime");
        String status = request.getParameter("status");
        if ("all".equals(status) || status == null)
            status = "-2014";
        // Integer status=Integer.valueOf(state);
        String key = request.getParameter("key");
        if (isEmpty(key)) {
            key = null;
        }
        Map<String, Object> map = new HashMap<String, Object>();
        if (!isEmpty(startTime)) {
            Date startDate = strToDate(startTime, "yyyy-MM-dd HH:mm");
            map.put("startTime", startDate);
        }
        if (!isEmpty(endTime)) {
            Date endDate = strToDate(endTime, "yyyy-MM-dd HH:mm");
            map.put("endTime", endDate);
        }
        map.put("status", status);
        map.put("key", key);
        return map;
    }

    /**
     * 取得本机IP地址
     *
     * @return
     */
    public static Long getIP() {
        String ip = "127.0.0.1";
        try {
            InetAddress LocalIP = InetAddress.getLocalHost();
            ip = LocalIP.toString();
        } catch (UnknownHostException e) {
        }
        return ip2int(ip);
    }
    /**
     * IP转成整型
     * @param ip
     * @return
     */
    public static Long ip2int(String ip)
    {
        Long num = 0L;
        if (ip == null){
            return num;
        }

        try{
            ip = ip.replaceAll("[^0-9\\.]", ""); //去除字符串前的空字符
            String[] ips = ip.split("\\.");
            if (ips.length == 4){
                num = Long.parseLong(ips[0], 10) * 256L * 256L * 256L + Long.parseLong(ips[1], 10) * 256L * 256L + Long.parseLong(ips[2], 10) * 256L + Long.parseLong(ips[3], 10);
                num = num >>> 0;
            }
        }catch(NullPointerException ex){
            System.out.println(ip);
        }

        return num;
    }
    /**
     * 整型解析为IP地址
     * @param num
     * @return
     */
    public static String int2iP(Long num)
    {
        String str = null;
        Long[] tt = new Long[4];
        tt[0] = (num >>> 24) >>> 0;
        tt[1] = ((num << 8) >>> 24) >>> 0;
        tt[2] = (num << 16) >>> 24;
        tt[3] = (num << 24) >>> 24;
        str = (tt[0]) + "." + (tt[1]) + "." + (tt[2]) + "." + (tt[3]);
        return str;
    }
    /**
     * 把原字段为转为小驼峰样式
     *
     * @param fieldName
     * @return
     */
    public static String getFieldLittleCamel(String fieldName) {
        if (isEmpty(fieldName)) {
            return "";
        } else {
            String[] fn = fieldName.split("_");
            StringBuilder sb = new StringBuilder();

            for (int i = 0; i < fn.length; i++) {
                if (i == 0)
                    sb.append(fn[i].toLowerCase());
                else {
                    sb.append(toUpperCaseFirstOne(fn[i]));
                }
            }
            return sb.toString();
        }
    }

    /**
     * 把原字段为转为大驼峰样式
     *
     * @param fieldName
     * @return
     */
    public static String getFieldBigCamel(String fieldName) {
        fieldName = getFieldLittleCamel(fieldName);
        if (isEmpty(fieldName)) {
            return "";
        } else
            return toUpperCaseFirstOne(fieldName);
    }

    /**
     * 首字母转小写
     *
     * @param s
     * @return
     */
    public static String toLowerCaseFirstOne(String s) {
        if (Character.isLowerCase(s.charAt(0)))
            return s;
        else
            return (new StringBuilder()).append(Character.toLowerCase(s.charAt(0))).append(s.substring(1)).toString();
    }

    /**
     * 首字母转大写
     *
     * @param s
     * @return
     */
    public static String toUpperCaseFirstOne(String s) {
        if (Character.isUpperCase(s.charAt(0)))
            return s;
        else
            return (new StringBuilder()).append(Character.toUpperCase(s.charAt(0))).append(s.substring(1)).toString();
    }

    /**
     * 获取对应的数据类型
     * @param language
     * @param dbType
     * @return
     */
    public static String getDataType(String cacheKey,String language, String dbType) {

        Map map = new HashMap();
        Object cache=EhCacheUtil.getInstance().get(cacheKey, language);
        if (cache== null) {
            SAXReader reader = new SAXReader();
            URL url = StringUtils.class.getClassLoader().getResource("config/DatatypeMap.xml");
            String path = url.getPath();
            // 读取一个文件，把这个文件转换成Document对象
            File file = new File(path);
            Document document = null;
            try {
                document = reader.read(file);
            } catch (DocumentException e) {
                e.printStackTrace();
            }
            // 获取根元素
            Element root = document.getRootElement();
            Element element=root.element("DbToJava");
            List<Element> types=element.elements();
            for (Element e:types)
            {
                map.put(e.attribute("key").getText(),e.attribute("value").getText());
                System.out.println(e.attribute("value").getText());
            }

            EhCacheUtil.getInstance().put(cacheKey, language, map);
        } else
            map = (Map) cache;
        if (map.containsKey(dbType)) {
            return map.get(dbType) + "";
        }
        return "";
    }

}
